﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FreeRedis;
using Newtonsoft.Json;

namespace LeafCore.Commons.Utils
{
    public static class RedisHelper
    {
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="seconds"></param>
        /// <returns></returns>

        public static async Task<bool> SetTAsync<T>(this RedisClient client, string key, T value, int seconds = 0)
        {
            if (key.IsNullOrEmpty() || value == null)
            {
                return false;
            }

            seconds = seconds < 0 ? 0 : seconds;

            var valueStr = value.ToJsonString();
            await client.SetAsync(key, valueStr, seconds);

            return true;
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="seconds"></param>
        /// <returns></returns>

        public static bool SetT<T>(this RedisClient client, string key, T value, int seconds = 0)
        {
            if (key.IsNullOrEmpty() || value == null)
            {
                return false;
            }

            seconds = seconds < 0 ? 0 : seconds;

            var valueStr = value.ToJsonString();
            client.Set(key, valueStr, seconds);

            return true;
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="client"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public static bool SetT<T>(this RedisClient client, string key, T value, TimeSpan timeout)
        {
            if (key.IsNullOrEmpty() || value == null)
            {
                return false;
            }

            var valueStr = value.ToJsonString();
            client.Set(key, valueStr, timeout);

            return true;
        }

        /// <summary>
        /// 获取缓存数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static async Task<T?> GetTAsync<T>(this RedisClient client, string key)
        {
            if (key.IsNullOrEmpty())
            {
                return default;
            }

            var valueStr = await client.GetAsync(key);
            if (valueStr.IsNullOrEmpty())
            {
                return default;
            }

            return JsonConvert.DeserializeObject<T>(valueStr);
        }

        /// <summary>
        /// 获取缓存数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T? GetT<T>(this RedisClient client, string key)
        {
            if (key.IsNullOrEmpty())
            {
                return default;
            }

            var valueStr = client.Get(key);
            if (valueStr.IsNullOrEmpty())
            {
                return default;
            }

            return JsonConvert.DeserializeObject<T>(valueStr);
        }

        /// <summary>
        /// 列表添加数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="client"></param>
        /// <param name="key"></param>
        /// <param name="elements"></param>
        /// <returns></returns>
        public static long LPushT<T>(this RedisClient client, string key, params T[] elements)
        {
            if (key.IsNullOrEmpty() || elements.IsNullOrEmpty())
            {
                return 0;
            }
            var elementStrs = elements.Select(o => o.ToJsonString()).ToArray();
            return client.LPush(key, elementStrs);
        }

        /// <summary>
        /// 获取列表数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="client"></param>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public static T[]? LRangeT<T>(this RedisClient client, string key, long start, long stop) where T : class
        {
            var elements = client.LRange(key, start, stop);
            if (elements.IsNullOrEmpty())
            {
                return null;
            }

            return elements.Select(o => o.ToEntity<T>()).ToArray();
        }
    }
}
